package com.yz.yrpc.config;


import com.yz.yrpc.annotation.YrpcClient;
import com.yz.yrpc.annotation.YrpcScan;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;
import java.util.Map;
import java.util.Set;

/**
 * @author shanchong
 * @date 2019-06-30
 **/
public class RpcBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        final Map<String, Object> annotationAttributes = annotationMetadata.getAnnotationAttributes(YrpcScan.class.getName());
        final String value = (String) annotationAttributes.get("value");
        final RpcClassPathBeanDefinitionScanner scanner = new RpcClassPathBeanDefinitionScanner(beanDefinitionRegistry);
        scanner.addIncludeFilter(new TypeFilter() {
            @Override
            public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
                return true;
            }
        });
        final Set<BeanDefinitionHolder> beanDefinitionHolders = scanner.doScan(value);
        for (BeanDefinitionHolder beanDefinitionHolder :beanDefinitionHolders){
            GenericBeanDefinition beanDefinition = (GenericBeanDefinition)beanDefinitionHolder.getBeanDefinition();
            final String beanClassName = beanDefinition.getBeanClassName();
            beanDefinition.setBeanClass(RpcFactoryBean.class);
            try {
                beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(Class.forName(beanClassName));
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
        }

    }


}